<?php

class ImmutableDateTime {
	private $value;
	public static function Parse($value,$format){
		return new ImmutableDateTime(DateTime::createFromFormat($format,$value));
	}
	public static function Make($year,$month,$day,$hours=0,$minutes=0,$seconds=0){
		$r = new ImmutableDateTime();
		$r->value->SetDate($year,$month,$day);
		$r->value->SetTime($hours,$minutes,$seconds);
		return $r;
	}
	public function __construct(DateTime $value=null){
		$this->value = is_null($value) ? new DateTime() : clone $value;
	}
	public function GetYear(){ return intval($this->value->format('Y')); }
	public function GetMonth(){ return intval($this->value->format('m')); }
	public function GetDay(){ return intval($this->value->format('d')); }
	public function GetHours(){ return intval($this->value->format('H')); }
	public function GetMinutes(){ return intval($this->value->format('i')); }
	public function GetSeconds(){ return intval($this->value->format('s')); }
	
	public function GetDate(){ return self::Parse($this->value->format('Ymd000000'),'YmdHis'); }
	public function GetTime(){ return self::Parse($this->value->format('00010101His'),'YmdHis'); }
	public function AsDateTime(){ return clone $this->value; }
	public function AsInt(){ return $this->value->getTimestamp(); }

	
	
	public function AddYears($value){ 
		$r = new ImmutableDateTime($this->value);
		if ($value < 0)
			$r->value->sub('P'.abs($value).'Y');
		else
			$r->value->add('P'.$value.'Y');
		return $r;
	}
	public function AddMonths($value){ 
		$r = new ImmutableDateTime($this->value);
		if ($value < 0)
			$r->value->sub('P'.abs($value).'M');
		else
			$r->value->add('P'.$value.'M');
		return $r;
	}
	public function AddDays($value){ 
		$r = new ImmutableDateTime($this->value);
		if ($value < 0)
			$r->value->sub('P'.abs($value).'D');
		else
			$r->value->add('P'.$value.'D');
		return $r;
	}
	public function AddHours($value){ 
		$r = new ImmutableDateTime($this->value);
		if ($value < 0)
			$r->value->sub('T'.abs($value).'H');
		else
			$r->value->add('T'.$value.'H');
		return $r;
	}
	public function AddMinutes($value){ 
		$r = new ImmutableDateTime($this->value);
		if ($value < 0)
			$r->value->sub('T'.abs($value).'M');
		else
			$r->value->add('T'.$value.'M');
		return $r;
	}
	public function AddSeconds($value){ 
		$r = new ImmutableDateTime($this->value);
		if ($value < 0)
			$r->value->sub('T'.abs($value).'S');
		else
			$r->value->add('T'.$value.'S');
		return $r;
	}

	public function AddTimeSpan(ImmutableTimeStamp $value){
		return $this->AddSeconds($value->GetTotalSeconds());
	}
	
	public function Format($format){
		return $this->value->format($format);
	}
}

?>
